<?php
// +----------------------------------------------------------------------
// | B5Yii2CMF V3.0 [快捷通用基础管理开发平台]
// +----------------------------------------------------------------------
// | Author: 冰舞 <357145480@qq.com>
// +----------------------------------------------------------------------
declare (strict_types=1);

namespace api\utils\libs;

use common\models\system\Admin;
use common\models\system\AppToken;
use Throwable;
use yii\db\Exception;
use yii\db\StaleObjectException;

class TokenMethod
{
    /**
     * 查询token信息
     * @param string $token
     * @param string $type 用户类型
     * @param string $plat 平台
     * @param bool $autoRefresh 自动更新有效期
     * @return AppToken|null
     */
    public static function getToken(string $token = '', string $type = 'admin', string $plat = 'web', bool $autoRefresh = true): ?AppToken
    {
        $token = trim($token);
        if (!$token || !ctype_alnum($token) || strlen($token) != 32) return null;
        $record = AppToken::findOne(['token' => $token, 'plat' => $plat, 'type' => $type]);
        if (!$record) return null;

        if ($record->exp_time < time()) {
            try {
                $record->delete();
            } catch (StaleObjectException | Throwable $e) {
            }
            return null;
        }

        // 当有效期小于6小时，更新有效期
        if ($autoRefresh && $record->exp_time < time() - 6 * 3600) {
            $record->exp_time = time() + 7 * 24 * 3600;
            try {
                $record->save(false);
            } catch (Exception $e) {
            }
        }
        return $record;
    }

    public static function setToken($id, string $type = 'admin', string $plat = 'web', string $extend = ''): string
    {
        if (!$id) return '';
        $record = AppToken::findOne(['user_id' => $id, 'type' => $type, 'plat' => $plat]);

        if (!$record) {
            $record = new AppToken();
            $record->user_id = $id;
            $record->type = $type;
            $record->plat = $plat;
        }
        $nowTime = time();
        $key = $id . $nowTime . $type . $plat . mt_rand(100, 999);
        $token = md5($key);
        $exp_time = $nowTime + 7 * 24 * 3600;
        $record->exp_time = $exp_time;
        $record->extend = $extend;
        $record->token = $token;

        try {
            if ($record->save(false)) return $token;
        } catch (Exception $e) {
            var_dump($e->getMessage());die;
        }
        return '';
    }

    /**删除某个用户token
     * @param int $user_id
     * @param string $plat
     * @param string $type \
     */
    public static function clearToken(int $user_id, string $plat, string $type)
    {
        if (!$user_id || !$type || !$plat) return;
        $info = AppToken::findOne(['user_id' => $user_id, 'type' => $type, 'plat' => $plat]);
        if (!$info) return;
        try {
            $info->delete();
        } catch (StaleObjectException | Throwable $e) {
        }
    }

    public static function clearTokenByUserName(string $username, string $plat, string $type)
    {
        if (!$username || !$type || !$plat) return;
        $user = null;
        if ($type == 'admin') {
            $user = Admin::findOne(['user_name' => $username]);
        }
        if (!$user) return;
        self::clearToken($user->id, $plat, $type);
    }
}